import Food from "./Food";
import ScorePanel from "./ScorePanel";
import Snake from "./Snake";

// 游戏控制,控制其他的所有类
class GameControl {
  // 定义3个属性
  // 蛇
  snake: Snake;
  // 食物
  food: Food;
  // 记分牌
  scorePanel: ScorePanel;

  // 创建一个属性来存储蛇的移动方向,也就是按键的方向
  direction: string = "";
  // 创建一个属性用来记录游戏是否结束
  isLive: boolean = true;

  constructor() {
    this.snake = new Snake();
    this.food = new Food();
    this.scorePanel = new ScorePanel();

    this.init();
  }

  // 游戏的初始化方法, 调用后游戏就开始
  init() {
    // 绑定键盘按键按下的事件
    document.addEventListener("keydown", this.keydownHandler.bind(this));
    // 调用蛇移动的方法
    this.snakeMove();
  }
  // 创建一个键盘按下的事件
  keydownHandler(event: KeyboardEvent) {
    /**
     * ArrowUp , Up(ie)
     * ArrowDown , Down(ie)
     * ArrowLeft , Left(ie)
     * ArrowRight , Right(ie)
     * 赋值之前需要检查方向
     * 检查event.key是否合法,用户是否按了正确的按键
     */
    // console.log(event.key);
    this.direction = event.key;
  }
  // 创建一个蛇移动的方法
  snakeMove() {
    /**
     * 根据方向 this.direction 来使蛇的位置改变
     * 向上 top 减少
     * 向下 top 增加
     * 向左 left 减少
     * 向右 left 增加
     */
    let X = this.snake.X;
    let Y = this.snake.Y;
    // 根据按键的方向修改X值和Y值
    switch (this.direction) {
      case "ArrowUp":
      case "Up":
        // 向上移动 top 减少
        Y -= 10;
        break;
      case "ArrowDown":
      case "Down":
        // 向上移动 top 增加
        Y += 10;
        break;
      case "ArrowLeft":
      case "Left":
        // 向左 left减少
        X -= 10;
        break;
      case "ArrowRight":
      case "Right":
        // 向右 left 增加
        X += 10;
        break;
    }
    // 检查蛇是否吃到食物
    this.checkEat(X, Y);
    // 错误捕获
    try {
      this.snake.X = X;
      this.snake.Y = Y;
    } catch (err: any) {
      // 进入到catch, 出现了异常,游戏结束,弹出一个提示
      alert(err.message + ", 游戏结束");
      this.isLive = false;
    }
    // 开启一个定时器
    this.isLive &&
      setTimeout(
        this.snakeMove.bind(this),
        300 - (this.scorePanel.level - 1) * 30
      );
  }
  // 检查蛇是否吃到食物
  checkEat(X: number, Y: number) {
    if (X === this.food.X && Y === this.food.Y) {
      // 修改食物的位置
      this.food.change();
      // 分数增加
      this.scorePanel.addScore();
      // 蛇增加一节
      this.snake.addBody();
    }
  }
}

export default GameControl;
